#include "ADC.h"	

/* Sample result with channel information (channel 6 to channel 10) */
uint32_t adcResult[6] = {0};
/*Sample data value (channel 6 to channel 10) */
uint16_t dataResult[6] = {0};
/*Sample channel value (channel 6 to channel 10) */
uint16_t chResult[6] = {0};


ADC_Config_t subcaseAdcCfg=
{
    ADC_RESOLUTION_12BIT,    /* ADC 12-bit resolution */
    ADC_VREF_EXTERNAL,       /* Internal Vref_H to 5V, Vref_L to 0V reference */
    ADC_TDG_TRIGGER,         /* TDG trigger select */
    ADC_CONVERSION_SINGLE,   /* ADC single conversion */
    ADC_AVGS_8,              /* 8 times average for each conversion*/
    100,                     /* Set the time interval between two samples when average is enabled or
                    in continues mode. Please refer to STS definition in RM to see the constraint */
}; 

ADC_ChannelConfig_t adcChannelCfg = 
{
    ADC_SINGLE_MODE,  /* Single-Ended Mode Selected */
    ADC_P_CH0,        /* Single mode, channel[7] and vssa */
    ADC_N_NONE,       /* Single mode, N-channel donn't need to configure */
};

ADC_TDGTriggerConfig_t  adcTriggerConfig = 
{
    ADC_LOOP_MODE,    /* Loop mode Selected */
    ADC_P_CH0,        /* CMD0: channel 0; */
    ADC_P_CH1,        /* CMD1: channel 1; */
    ADC_P_CH2,        /* CMD2: channel 2; */
    ADC_P_CH3,        /* CMD3: channel 3; */
    ADC_P_CH8,        /* CMD4: channel 4; */
	ADC_P_CH8,        /* CMD4: channel 4; */

};

//ADC_TDGTriggerConfig_t  adcTriggerConfig2 = 
//{
//    ADC_LOOP_MODE,    /* Loop mode Selected */
//    ADC_P_CH6,        /* CMD0: channel 6; */
//    ADC_P_CH7,        /* CMD1: channel 7; */
//    ADC_P_CH8,        /* CMD2: channel 8; */
//    ADC_P_CH9,        /* CMD3: channel 9; */
//    ADC_P_CH10,       /* CMD4: channel 10; */
//    ADC_P_CH11,       /* CMD5: channel 11; all CMDs can be configured as different channels */
//};



/* watermark interrupt handler */
static void ADC_FifoWaterMakerIntCallback()
{
    uint32_t i = 0;
    /* Get data for channel 6 to channel 10, suggest to discard the first sampled data due to the instability of it*/
    for(i=0; i<6; i++)
    {
        adcResult[i] = ADC_GetConversionResult(ADC0_ID);
        dataResult[i] = adcResult[i] & 0xfff;
        chResult[i] = (adcResult[i] >> 12) & 0x1f;
    }

}




static void AdcInit(void)
{
	
	PORT_PinmuxConfig(PORT_A, GPIO_0, PTA0_ADC0_CH0); //AI_KL15_CHE
	PORT_PinmuxConfig(PORT_A, GPIO_1, PTA1_ADC0_CH1); //AI_KL30_CHE
	PORT_PinmuxConfig(PORT_A, GPIO_6, PTA6_ADC0_CH2); //AI_LED_CHE
	PORT_PinmuxConfig(PORT_A, GPIO_7, PTA7_ADC0_CH3); //AI_NTC_CHE
	PORT_PinmuxConfig(PORT_C, GPIO_0, PTC0_ADC0_CH8); //AI_LDO_CHE
	
	/* mod value, single, divide4, SW trig, clear to mod  */
	 TDG_InitConfig_t config=
	{
			0xFA0, TDG_COUNT_INFINITY, TDG_CLK_DIVIDE_4, TDG_TRIG_SW, TDG_UPDATE_IMMEDIATELY, TDG_CLEAR_MODULATOR
	};

	TDG_DelayOutputConfig_t doConfig[1] =
	{
			{TDG_DO_0, 0xFA0, ENABLE}, 
	};


	const TDG_ChannelConfig_t chConfig =
	{
			TDG_CHANNEL_0, 0x016, 1, doConfig
	};	
	
	
	ADC_InstallCallBackFunc(ADC0_ID, ADC_FWM_INT, ADC_FifoWaterMakerIntCallback);
	
    ADC_SoftwareReset(ADC0_ID);/* Reset software */
	
    ADC_Init(ADC0_ID,&subcaseAdcCfg);/* Initialize ADC */
	
    ADC_FifoDepthRedefine(ADC0_ID, 16U);/*Configure the FIFO depth*/
	
    ADC_FifoWatermarkConfig(ADC0_ID,5U);	/* Set ADC watermark*/
	
    ADC_ChannelConfig(ADC0_ID, &adcChannelCfg);/* Configure input channel*/
    ADC_IntMask(ADC0_ID, ADC_INT_ALL, MASK);/* unmask FIFO watermark interrupt */
    ADC_IntMask(ADC0_ID, ADC_FWM_INT, UNMASK);
	
    ADC_TDGTriggerConfig(ADC0_ID,&adcTriggerConfig);/* Set trigger mode */
    ADC_IntClear(ADC0_ID, ADC_FWM_INT); /* Clear FWM interrupt */
    NVIC_EnableIRQ(ADC0_IRQn); /* Enable ADC interrupt */
    ADC_Enable(ADC0_ID); /* Enable ADC module */
	
    TDG_InitConfig(TDG0_ID, &config); /* Initialize TDG */
    TDG_ChannelDelayOutputConfig(TDG0_ID, &chConfig, ENABLE); /* Set TDG delay output*/
    TDG_Enable(TDG0_ID, ENABLE);/* enable TDG */
    TDG_LoadCmd(TDG0_ID); /* Load channel configuration */ 
    TDG_SoftwareTrig(TDG0_ID); /*Trigger TDG*/
}



void Ex_Adc_Init(void)
{
	AdcInit();

}